<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Genivia - The CURL plugin</title>
<link href="genivia_tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="genivia_content.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="top">
 <div id="titlearea">
  <table height="72px" width="100%" cellspacing="0" cellpadding="0">
   <tbody>
    <tr>
     <td width="10%">&nbsp;</td>
     <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td>
     <td class="tab_home"><a href="https://www.genivia.com">Home</a></td>
     <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td>
     <td>
      <div style="float: right; font-size: 18px; font-weight: bold;">The CURL plugin</div>
      <br>
      <div style="float: right; font-size: 10px;">updated Tue Jan 15 2019 by Robert van Engelen</div>
     </td>
     <td width="10%">&nbsp;</td>
    </tr>
   </tbody>
  </table>
 </div>
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">The CURL plugin </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#curl_0">Overview</a></li>
<li class="level1"><a href="#curl_1">CURL plugin setup</a></li>
<li class="level1"><a href="#curl_2">Configuration and settings</a></li>
<li class="level1"><a href="#curl_3">SOAP client example</a></li>
<li class="level1"><a href="#curl_4">JSON REST example</a></li>
</ul>
</div>
<div class="textblock"><h1><a class="anchor" id="curl_0"></a>
Overview</h1>
<p>The CURL plugin for gSOAP provides a bridge for the gSOAP engine to use libcurl for internet communications. While gSOAP provides a full HTTP stack, libcurl can be used to support additional protocols and features by replacing gSOAP's HTTP stack.</p>
<h1><a class="anchor" id="curl_1"></a>
CURL plugin setup</h1>
<p>To use the CURL plugin:</p><ol type="1">
<li>Add <code>#include "plugin/curlapi.h"</code> to your client-side code and compile your code together with <code><a class="el" href="curlapi_8c.html">plugin/curlapi.c</a></code>. Link your code with libcurl.</li>
<li>Add <code>curl_global_init(CURL_GLOBAL_ALL)</code> at the start of your program to initialize CURL. Add <code>curl_global_cleanup()</code> at the end of your program.</li>
<li>In your source code where you create a <code>soap</code> context, register the plugin with this <code>soap</code> context, Or use the <code>soap</code> member of a soapcpp2-generated C++ proxy class. Use <code>soap_register_plugin(soap, soap_curl)</code> to register.</li>
<li>Alternatively, if you have a <code>CURL *curl</code> handle already set up, then register the plugin with <code>soap_register_plugin_arg(soap, soap_curl, curl)</code>. The benefit of this is that you can set CURL options of the handle. Do not delete this handle until the <code>soap</code> context is deleted.</li>
<li>If you register multiple other plugins with the context, you should register the CURL plugin always first.</li>
</ol>
<p>The plugin is not limited to SOAP calls, you can use it with XML REST and JSON in gSOAP. The plugin registry steps are the same for any client-side API service calls.</p>
<p>The CURL plugin supports SOAP with MTOM attachments, including streaming MTOM. Other plugins can be combined with this plugin, such as WSSE for WS-Security.</p>
<dl class="section note"><dt>Note</dt><dd>The CURL plugin increases the overhead of HTTP calls compared to the gSOAP HTTP stack. The overhead is due to buffering of the entire outbound message before sending and buffering of the entire message received. By contrast, gSOAP uses a streaming approach and only buffers the socket communications to (de)serialize XML directly into C/C++ data.</dd></dl>
<h1><a class="anchor" id="curl_2"></a>
Configuration and settings</h1>
<p>To use the CURL plugin, register the plugin with the current <code>soap</code> context using <code>soap_register_plugin(soap, soap_curl)</code>. This also creates a new CURL handle that is internally used by the plugin until the <code>soap</code> context is deleted. For C++ proxy classes generated with soapcpp2, register the plugin with the <code>soap</code> member of the proxy class.</p>
<p>The gSOAP HTTP chunked transfer mode <code>SOAP_IO_CHUNK</code> and timeout settings are also used by the CURL plugin, when set, as follows:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line">...</div><div class="line">struct soap *soap;</div><div class="line">curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">soap = soap_new1(SOAP_IO_CHUNK | SOAP_XML_INDENT);</div><div class="line">soap_register_plugin(soap, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>);</div><div class="line">soap-&gt;connect_timeout = 60;  <span class="comment">// 1 minute</span></div><div class="line">soap-&gt;send_timeout = 10;     <span class="comment">// 10 seconds</span></div><div class="line">soap-&gt;recv_timeout = 10;     <span class="comment">// 10 seconds</span></div><div class="line">soap-&gt;transfer_timeout = 20; <span class="comment">// 20 seconds</span></div><div class="line">...</div><div class="line"><span class="comment">// client program runs</span></div><div class="line">...</div><div class="line">soap_destroy(soap);</div><div class="line">soap_end(soap);</div><div class="line">soap_free(soap);</div><div class="line">curl_global_cleanup();</div></div><!-- fragment --><p>It is strongly recommended to set timeouts. The timeout values specified here are just examples. Actual values depend on the application's performance characteristics.</p>
<p>HTTP proxy settings are used by the CURL plugin. You can specify the HTTP proxy settings <code>soap-&gt;proxy_host</code> and <code>soap-&gt;proxy_port</code> with the HTTP proxy host and port, respectively, and specify the HTTP proxy access credentials <code>soap-&gt;proxy_userid</code> and <code>soap-&gt;proxy_passwd</code>.</p>
<p>Also compression is used by the CURL plugin when enabled with <code>SOAP_ENC_ZLIB</code>:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line">...</div><div class="line">struct soap *soap;</div><div class="line">curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">soap = soap_new1(SOAP_IO_CHUNK | SOAP_ENC_ZLIB | SOAP_XML_INDENT);</div><div class="line">soap_register_plugin(soap, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>);</div><div class="line">...</div><div class="line"><span class="comment">// client program runs</span></div><div class="line">...</div><div class="line">soap_destroy(soap);</div><div class="line">soap_end(soap);</div><div class="line">soap_free(soap);</div><div class="line">curl_global_cleanup();</div></div><!-- fragment --><p>When an transmission error occurs, use <code>soap_curl_reset(soap)</code> to reset the plugin. This ensures that the gSOAP IO operations are reset and will behave again normally.</p>
<p>Alternatively, you can create your own <code>CURL *curl</code> handle, configure it, and pass it to the plugin as follows:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line">...</div><div class="line">struct soap *soap;</div><div class="line">CURL *curl;</div><div class="line">curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">curl = curl_easy_init();</div><div class="line">curl_easy_setopt(data-&gt;curl, CURLOPT_CONNECTTIMEOUT, 60L);</div><div class="line">curl_easy_setopt(data-&gt;curl, CURLOPT_TIMEOUT, 10L);</div><div class="line">soap = soap_new1(SOAP_XML_INDENT);</div><div class="line">soap_register_plugin_arg(soap, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>, curl);</div><div class="line">...</div><div class="line"><span class="comment">// client program runs</span></div><div class="line">...</div><div class="line">soap_destroy(soap);</div><div class="line">soap_end(soap);</div><div class="line">soap_free(soap);</div><div class="line">curl_easy_cleanup(curl);</div><div class="line">...</div><div class="line">curl_global_cleanup();</div></div><!-- fragment --><p>Note that C++ proxy classes generated by soapcpp2 with option <code>-j</code> have a <code>soap</code> member that should be used to register the plugin with:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line">...</div><div class="line">Proxy proxy(SOAP_XML_INDENT);</div><div class="line">CURL *curl;</div><div class="line">curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">curl = curl_easy_init();</div><div class="line">curl_easy_setopt(data-&gt;curl, CURLOPT_CONNECTTIMEOUT, 60L);</div><div class="line">curl_easy_setopt(data-&gt;curl, CURLOPT_TIMEOUT, 10L);</div><div class="line">soap_register_plugin_arg(proxy.soap, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>, curl);</div><div class="line">...</div><div class="line"><span class="comment">// make calls with the proxy object</span></div><div class="line">...</div><div class="line">proxy.destroy();</div><div class="line">curl_easy_cleanup(curl);</div><div class="line">...</div><div class="line">curl_global_cleanup();</div></div><!-- fragment --><h1><a class="anchor" id="curl_3"></a>
SOAP client example</h1>
<p>This example shows a calculator client application with CURL and gSOAP.</p>
<p>The soapcpp2 command is applied to <code>calc.h</code> with <code>soapcpp2 -c -CL calc.h</code>, where <code>calc.h</code> is:</p>
<div class="fragment"><div class="line"><span class="comment">//gsoap ns service name:            calc Simple calculator service described at https://www.genivia.com/dev.html</span></div><div class="line"><span class="comment">//gsoap ns service protocol:        SOAP</span></div><div class="line"><span class="comment">//gsoap ns service style:           rpc</span></div><div class="line"><span class="comment">//gsoap ns service encoding:        encoded</span></div><div class="line"><span class="comment">//gsoap ns service namespace:       http://websrv.cs.fsu.edu/~engelen/calc.wsdl</span></div><div class="line"><span class="comment">//gsoap ns service location:        http://websrv.cs.fsu.edu/~engelen/calcserver.cgi</span></div><div class="line"></div><div class="line"><span class="comment">//gsoap ns schema namespace:        urn:calc</span></div><div class="line"></div><div class="line"><span class="comment">//gsoap ns service method: add Sums two values</span></div><div class="line"><span class="keywordtype">int</span> ns__add(<span class="keywordtype">double</span> a, <span class="keywordtype">double</span> b, <span class="keywordtype">double</span> *result);</div><div class="line"></div><div class="line"><span class="comment">//gsoap ns service method: sub Subtracts two values</span></div><div class="line"><span class="keywordtype">int</span> ns__sub(<span class="keywordtype">double</span> a, <span class="keywordtype">double</span> b, <span class="keywordtype">double</span> *result);</div><div class="line"></div><div class="line"><span class="comment">//gsoap ns service method: mul Multiplies two values</span></div><div class="line"><span class="keywordtype">int</span> ns__mul(<span class="keywordtype">double</span> a, <span class="keywordtype">double</span> b, <span class="keywordtype">double</span> *result);</div><div class="line"></div><div class="line"><span class="comment">//gsoap ns service method: div Divides two values</span></div><div class="line"><span class="keywordtype">int</span> ns__div(<span class="keywordtype">double</span> a, <span class="keywordtype">double</span> b, <span class="keywordtype">double</span> *result);</div><div class="line"></div><div class="line"><span class="comment">//gsoap ns service method: pow Raises a to b</span></div><div class="line"><span class="keywordtype">int</span> ns__pow(<span class="keywordtype">double</span> a, <span class="keywordtype">double</span> b, <span class="keywordtype">double</span> *result);</div></div><!-- fragment --><p>This generates <code>soapStub.h</code>, <code>soapH.h</code>, <code>soapC.c</code>, <code>soapClient.c</code>, and <code>calc.nsmap</code>.</p>
<p>To keep this example small, the main program uses the calculator service to add two values:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;calc.nsmap&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> server[] = <span class="stringliteral">&quot;http://websrv.cs.fsu.edu/~engelen/calcserver.cgi&quot;</span>;</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)</div><div class="line">{</div><div class="line">  <span class="keyword">struct </span>soap *soap = soap_new1(SOAP_XML_INDENT);</div><div class="line">  <span class="keywordtype">double</span> result;</div><div class="line">  curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">  soap_register_plugin(soap, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>);</div><div class="line">  <span class="keywordflow">if</span> (soap_call_ns__add(soap, server, <span class="stringliteral">&quot;&quot;</span>, 2.0, 3.0, &amp;result))</div><div class="line">  {</div><div class="line">    soap_print_fault(soap, stderr);</div><div class="line">    <a class="code" href="curlapi_8h.html#a5fcaf3eb999b523574f85ebed558953d">soap_curl_reset</a>(soap);</div><div class="line">  }</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    printf(<span class="stringliteral">&quot;2 +3 = %g\n&quot;</span>, result);</div><div class="line">  soap_destroy(soap);</div><div class="line">  soap_end(soap);</div><div class="line">  soap_free(soap);</div><div class="line">  curl_global_cleanup();</div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>We compile this example program together with <code>stdsoap2.c</code>, <code>soapC.c</code>, <code>soapClient.c</code>, <code><a class="el" href="curlapi_8c.html">plugin/curlapi.c</a></code> and we link it with libcurl.</p>
<p>As stated previously, to use a current <code>CURL *curl</code> handle that you have created, use <code>soap_register_plugin_arg(soap, soap_curl, curl)</code> to register the plugin.</p>
<h1><a class="anchor" id="curl_4"></a>
JSON REST example</h1>
<p>See the gSOAP <a href="https://www.genivia.com/doc/xml-rpc-json/html/index.html">JSON documentation</a> for details about using JSON with gSOAP in C and in C++.</p>
<p>A JSON client in C with CURL has the following outline:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="curlapi_8h.html">plugin/curlapi.h</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;json.h&quot;</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] = {{NULL,NULL,NULL,NULL}};</div><div class="line">...</div><div class="line">struct soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);</div><div class="line"><span class="keyword">struct </span>value *request = new_value(ctx);</div><div class="line"><span class="keyword">struct </span>value response;</div><div class="line">curl_global_init(CURL_GLOBAL_ALL);</div><div class="line">soap_register_plugin(ctx, <a class="code" href="curlapi_8h.html#aa2eec8873794a63af03b1ab21d762955">soap_curl</a>);</div><div class="line">... <span class="comment">// here we populate the request data to send</span></div><div class="line"><span class="keywordflow">if</span> (json_call(ctx, <span class="stringliteral">&quot;endpoint URL&quot;</span>, request, &amp;response))</div><div class="line">{</div><div class="line">  soap_print_fault(ctx, stderr);</div><div class="line">  <a class="code" href="curlapi_8h.html#a5fcaf3eb999b523574f85ebed558953d">soap_curl_reset</a>(ctx);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">  ... <span class="comment">// use the response data here</span></div><div class="line">}</div><div class="line">soap_destroy(ctx); <span class="comment">// delete objects</span></div><div class="line">soap_end(ctx);     <span class="comment">// delete data</span></div><div class="line">...                <span class="comment">// here we can make other calls etc.</span></div><div class="line">soap_free(ctx);    <span class="comment">// delete the context</span></div><div class="line">curl_global_cleanup();</div></div><!-- fragment --><p>As stated previously, to use a current <code>CURL *curl</code> handle that you have created, use <code>soap_register_plugin_arg(soap, soap_curl, curl)</code> to register the plugin.</p>
<p>JSON in C++ is similar to the C example shown with the benefit of the easy-to-use <a href="https://www.genivia.com/doc/xml-rpc-json/html/index.html#cpp">JSON C++ API</a>. </p>
</div></div><!-- contents -->
<hr class="footer">
<address class="footer">
Copyright (C) 2019, Robert van Engelen, Genivia Inc., All Rights Reserved.
</address>
<address class="footer"><small>
Converted on Tue Jan 15 2019 08:38:06 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address>
<br>
<div style="height: 246px; background: #DBDBDB;">
</body>
</html>
